package com.ruoyi.ring.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson2.JSON;
import com.google.gson.Gson;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.enums.*;
import com.ruoyi.common.utils.DateCalculationUtil;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.bean.Builder;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.ora.constant.BizConstants;
import com.ruoyi.ring.domain.*;
import com.ruoyi.ring.domain.dto.*;
import com.ruoyi.ring.domain.vo.*;
import com.ruoyi.ring.factory.AiFactory;
import com.ruoyi.ring.mapper.*;
import com.ruoyi.ring.service.*;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.service.ISysConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Slf4j
@Service
public class IRingPhysicalConditionServiceImpl implements IRingPhysicalConditionService {
    @Resource
    private IRingSleepDetailService ringSleepDetailService;
    @Resource
    private RingSleepInfoMapper ringSleepInfoMapper;
    @Resource
    private IRingSportRecordService ringSportRecordService;
    @Resource
    private IRingHealthPlanService ringHealthPlanService;
    @Resource
    private SysUserMapper sysUserMapper;
    @Resource
    private IRingUserSettingService ringUserSettingService;
    @Resource
    private IRingTodaySignService ringTodaySignService;
    @Resource
    private IDailyTagsService dailyTagsService;
    @Resource
    private IUserFoodInfoService userFoodInfoService;
    @Resource
    private ISysConfigService configService;
    @Resource
    private IRingExerciseDetailService ringExerciseDetailService;
    @Resource
    private IRingStressChangeInfoService ringStressChangeInfoService;
    @Resource
    private IRingEmotionalInfoService ringEmotionalInfoService;
    @Resource
    private RingHeartRateInfoMapper ringHeartRateInfoMapper;
    @Resource
    private RingHrvInfoMapper ringHrvInfoMapper;
    @Resource
    private RingBloodOxygenMapper ringBloodOxygenMapper;
    @Resource
    private RingStressChangeInfoMapper ringStressChangeInfoMapper;
    @Resource
    private RingEmotionalInfoMapper ringEmotionalInfoMapper;
    @Resource
    private UserFoodInfoMapper userFoodInfoMapper;

    @Resource
    private UserPhysiologyMapper userPhysiologyMapper;
    @Resource
    private UserPhysiologySetMapper userPhysiologySetMapper;

    @Override
    public RingTodaySign addTodaySign(RingTodaySignDTO ringTodaySignDTO) {
        long userId = SecurityUtils.getUserId();
        String deviceSn = ringTodaySignDTO.getDeviceSn();
        Date dailyVaule = DateUtils.dateTime(DateUtils.YYYY_MM_DD, DateUtils.getDate());
        RingTodaySign todaySign = ringTodaySignService.selectOneRingTodaySign(Builder.of(RingTodaySign::new).
                with(RingTodaySign::setDeviceSn,deviceSn).
                with(RingTodaySign::setDailyValue,dailyVaule).build());
        if(todaySign != null){
            return todaySign;
        }
        RingSleepDetail ringSleepDetail = ringSleepDetailService.selectOneRingSleepDetail(Builder.of(RingSleepDetail::new).
                with(RingSleepDetail::setDeviceSn,deviceSn).
                with(RingSleepDetail::setSleepType,SleepTypeEnums.LONG_SLEEP.getCode()).
                with(RingSleepDetail::setDailyValue,dailyVaule).build());


        RingHeartRateInfo heartRateInfo = ringHeartRateInfoMapper.selectOneRingHeartRateInfo(Builder.of(RingHeartRateInfo::new).
                with(RingHeartRateInfo::setDeviceSn, deviceSn).
                with(RingHeartRateInfo::setDailyValue, dailyVaule).build());
        if(ringSleepDetail != null && heartRateInfo != null){
            //卧床时间
            String bedRestTime = DateUtils.convertMinutesToChinese(ringSleepDetail.getTotalTime());

            // 深睡眠时间 */
            Integer deepTime = ringSleepDetail.getDeepTime();
            // 睡眠总时长 */
            Integer totalTime = ringSleepDetail.getTotalTime();
            //深睡比例
            double deepRate = 0;
            if(totalTime > 0){
                double val = (double) deepTime/totalTime;
                deepRate = NumberUtil.round(val* 100, 0).intValue();
            }

            List<SleepHomeRateVO.RingSleepHeartRate> list;
            //平均睡眠心率
            int average = 0;
            if(ringSleepDetail != null) {
                if (heartRateInfo != null) {
                    list = getSleepHeartRates(heartRateInfo.getHistoryDay(), heartRateInfo.getTimeInterval(), heartRateInfo.getHeartRateList().replace("null", "0").replace("255", "0"), ringSleepDetail);
                    int count = list.size();
                    if (count > 0) {
                        long totalSum = list.stream().mapToLong(rate -> rate.getValue()).sum();// 求和
                        average = (int) totalSum / count;
                    }
                }
            }

            PhysicalConditionDTO physicalConditionDTO = new PhysicalConditionDTO();
            physicalConditionDTO.setDeviceSn(deviceSn);
            physicalConditionDTO.setDailyValue(DateUtils.queryYesterday(dailyVaule));
            ConditionScoreVO conditionScoreVO = queryConditionScore(physicalConditionDTO);
            String aiContent = "昨日睡眠时长"+bedRestTime+
                    "，深睡占比" + deepRate +
                    "，心率波动平均为" + average +
                    "，事件记录总分是5分得：" + conditionScoreVO.getEventTotalScore() + "分" +
                    "，运动（步数、消耗卡路里、BMI指数、运动距离）总分是20分得：" + conditionScoreVO.getSportTotalScore() + "分" +
                    "，压力情绪总分是10分得：" + conditionScoreVO.getEmotionalStressScore() + "分" +
                    "，饮食总分是10分得：" + conditionScoreVO.getFoodTotalScore() + "分，" +
                    "通过以上描述生成一个我的"+DateUtils.dateTime(DateUtils.YYYY_MM_DD, DateUtils.getDate())+"日签文，返回什么签(只要三个字)，什么日(只要三个字)，健康评语，健康建议（今日宜），健康溯源，趣味彩蛋,例如{\"shenmeqian\":\"xxx\",\"shenmeri\":\"xxx\",\"jiankangpingyu\":\"xxx\",\"jiankangjianyi\":\"xxx\",\"jiangkangsuyuan\":\"xxx\",\"quweicaidan\":\"xxx\"}，不要其他任何内容";
            String jsonStr = AiFactory.build(BizConstants.AI_PLATFORM.getValue()).chatCompletions(aiContent);
            Gson gson = new Gson();
            Map<String, Object> resultMap = gson.fromJson(jsonStr, Map.class);

            RingTodaySign ringTodaySign = cn.hutool.core.convert.Convert.convert(RingTodaySign.class,ringTodaySignDTO);
            ringTodaySign.setUserId(userId);
            ringTodaySign.setDailyValue(dailyVaule);
            ringTodaySign.setLingTiao(resultMap.get("shenmeqian").toString());
            ringTodaySign.setSunPillar(resultMap.get("shenmeri").toString());
            ringTodaySign.setHealthReviews(resultMap.get("jiankangpingyu").toString());
            ringTodaySign.setHealthAdvice(resultMap.get("jiankangjianyi").toString());
            ringTodaySign.setHealthTraceability(resultMap.get("jiangkangsuyuan").toString());
            ringTodaySign.setFunEasterEggs(resultMap.get("quweicaidan").toString());
            int result = ringTodaySignService.insertRingTodaySign(ringTodaySign);
            return result > 0 ? ringTodaySign : null;
        }else {
            return new RingTodaySign();
//            throw new RuntimeException("无睡眠和心率信息，无法生成今日签！");
        }

    }
    /**
     * @param dateValue 时间
     * @param timeInterval 间隔
     * @param strValue 逗号隔开的字符串
     * @param sleepDetail 睡眠详情对象
     * @return 时间戳与心率的映射列表，按时间排序
     */
    public static List<SleepHomeRateVO.RingSleepHeartRate> getSleepHeartRates(Date dateValue,int timeInterval, String strValue, RingSleepDetail sleepDetail) {
        // 转换时间单位：秒 -> 毫秒
        long intervalMs = timeInterval * 60L * 1000L;
        // 获取睡眠时间段的时间戳
        long sleepStartMs = sleepDetail.getStartDate().getTime();
        long sleepEndMs = sleepDetail.getEndDate().getTime();
        // 心率数据起始时间戳
        long hrStartMs = dateValue.getTime();
        // 存储结果的有序映射
        List<SleepHomeRateVO.RingSleepHeartRate> list = new ArrayList<>();
        // 遍历所有心率数据点
        List<Integer> hrList = Arrays.stream(strValue.split(","))
                .map(String::trim) // 去除每个元素前后的空格
                .map(Integer::parseInt) // 转换为整数
                .collect(Collectors.toList());
        for (int i = 0; i < hrList.size(); i++) {
            // 计算当前心率数据点对应的时间戳
            long currentTimeMs = hrStartMs + (long)i * intervalMs;
            // 检查该时间点是否在睡眠期间内
            if (currentTimeMs >= sleepStartMs && currentTimeMs <= sleepEndMs) {
                int hrValue = hrList.get(i);
                // 仅添加有效心率值(排除0值)
                if (hrValue > 0) {
                    SleepHomeRateVO.RingSleepHeartRate sleepHeartRate = new SleepHomeRateVO.RingSleepHeartRate();
                    sleepHeartRate.setKey(DateUtils.calculateTimeAfterMinutes(DateUtil.date(currentTimeMs),0));
                    sleepHeartRate.setValue(hrValue);
                    list.add(sleepHeartRate);
                }
            }
        }
        return list;
    }

    @Override
    public ConditionScoreVO queryConditionScore(PhysicalConditionDTO physicalConditionDTO) {
        long userId;
        if(physicalConditionDTO.getUserId() != null){
            userId = physicalConditionDTO.getUserId();
        }else {
            userId = SecurityUtils.getUserId();
        }

        Date dailyValue = physicalConditionDTO.getDailyValue();
        ConditionScoreVO conditionScoreVO = new ConditionScoreVO();
        //睡眠
        List<RingSleepDetail> longSleepDetails = ringSleepDetailService.selectRingSleepDetailList(Builder.of(RingSleepDetail::new).
                with(RingSleepDetail::setDeviceSn, physicalConditionDTO.getDeviceSn()).
                with(RingSleepDetail::setDailyValue, dailyValue).
                with(RingSleepDetail::setSleepType, SleepTypeEnums.LONG_SLEEP.getCode()).build());
        RingSleepDetail longSleepDetail = longSleepDetails.stream().max(Comparator.comparingInt(RingSleepDetail::getTotalTime)).orElse(null);
        long sleepId = 0;
        int sleepDurationScore = 0;
        int deepSleepRatioScore = 0;
        int sleepEfficiencyScore = 0;
        int napScore = 0;
        if(longSleepDetail != null){
            sleepId = longSleepDetail.getId();
            sleepDurationScore = calculateSleepDurationScore(longSleepDetail);
            deepSleepRatioScore = calculateDeepSleepRatioScore(longSleepDetail);
            sleepEfficiencyScore = sleepEfficiency(longSleepDetail);
            List<RingSleepDetail> shortSleepDetails = ringSleepDetailService.selectRingSleepDetailList(Builder.of(RingSleepDetail::new).
                    with(RingSleepDetail::setDeviceSn, physicalConditionDTO.getDeviceSn()).
                    with(RingSleepDetail::setDailyValue, dailyValue).
                    with(RingSleepDetail::setSleepType, SleepTypeEnums.SHORT_NAP.getCode()).build());
            RingSleepDetail shortSleepDetail = shortSleepDetails.stream().max(Comparator.comparingInt(RingSleepDetail::getTotalTime)).orElse(null);
            napScore = calculateNapScore(shortSleepDetail);

        }
        conditionScoreVO.setSleepDurationScore(sleepDurationScore);
        conditionScoreVO.setDeepSleepRatioScore(deepSleepRatioScore);
        conditionScoreVO.setSleepEfficiencyScore(sleepEfficiencyScore);
        conditionScoreVO.setNapScore(napScore);
        conditionScoreVO.setSleepTotalScore(sleepDurationScore + deepSleepRatioScore + sleepEfficiencyScore + napScore);


        //事件
        List<DailyTags> dailyTagsList = dailyTagsService.selectDailyTagsList(Builder.of(DailyTags::new).
                with(DailyTags::setDailyValue, dailyValue).
                with(DailyTags::setUserId, userId).build()).stream().limit(5).collect(Collectors.toList());
        int eventScore = dailyTagsList.stream().map(d -> {
            try {
                return Integer.valueOf(d.getRecordScores());
            } catch (NumberFormatException | NullPointerException e) {
                // 处理转换失败的情况，这里返回0表示忽略无效值
                return 0;
            }
        }).mapToInt(Integer::intValue).sum();// shiji
        int eventTotalScore = eventScore > 5 ? 5 : eventScore == 0 ? 0 : -5 > eventScore ? -5 : eventScore;//事件总分数
        List<EventScoreVO> eventScoreVOList = new ArrayList<>();
        for(int i = 0; i < dailyTagsList.size(); i++){
            DailyTags d = dailyTagsList.get(i);
            EventScoreVO eventScoreVO = new EventScoreVO();
            eventScoreVO.setEventInfo(i == 0 ? "事件1" : i == 1 ? "事件2" : i == 2 ? "事件3" : i == 3 ? "事件4" : i == 4 ? "事件5" : "");
            eventScoreVO.setRecordScores(d.getRecordScores());
            eventScoreVOList.add(eventScoreVO);
        }
        conditionScoreVO.setEventTotalScore(eventTotalScore);
        conditionScoreVO.setEventScoreVOList(eventScoreVOList);

        //运动步数
        RingSportRecord sportRecord= ringSportRecordService.selectOneRingSportRecord(Builder.of(RingSportRecord::new).
                with(RingSportRecord::setCreateTime, dailyValue).
                with(RingSportRecord::setDeviceSn, physicalConditionDTO.getDeviceSn()).build());
        RingUserSetting userSetting = ringUserSettingService.selectOneRingUserSetting(Builder.of(RingUserSetting::new).with(RingUserSetting::setUserId, userId).build());
        int bmiScore = 0;
        int stepsScore = 0;
        int distanceScore = 0;
        int caloriesScore = 0;
        if(sportRecord != null) {
            SysUser sysUser = sysUserMapper.queryUserHealthQuestion(userId);
            int height = sysUser.getHeight();//身高
            double weight = sysUser.getWeight();//体重
            bmiScore = BMICalculator(Double.parseDouble(String.valueOf(height)),weight);


            int actualSteps = userSetting != null ? userSetting.getSteps() : 0;
            int targetSteps = sportRecord.getSteps();//步数
            stepsScore = calculateStepScore(actualSteps, targetSteps);

            int distance = sportRecord.getDistance();//距离
            distanceScore = calculateDistanceScore(distance);

            int actualCalories = userSetting != null ? userSetting.getCalories() : 0;
            int targetCalories = sportRecord.getCalories();//卡路里
            caloriesScore = calculateCalorieScore(Convert.toDouble(actualCalories), Convert.toDouble(targetCalories));
        }
        conditionScoreVO.setBmiScore(bmiScore);
        conditionScoreVO.setStepsScore(stepsScore);
        conditionScoreVO.setDistanceScore(distanceScore);
        conditionScoreVO.setCaloriesScore(caloriesScore);
        conditionScoreVO.setSportTotalScore(bmiScore + stepsScore + distanceScore + caloriesScore);

        //情绪
        List<RingEmotionalInfo> ringEmotionalInfos =ringEmotionalInfoMapper.selectRingEmotionalInfoList(Builder.of(RingEmotionalInfo::new).
                with(RingEmotionalInfo::setDailyValue, dailyValue).
                with(RingEmotionalInfo::setDeviceSn, physicalConditionDTO.getDeviceSn()).build());
        // 使用映射创建比较器
        Comparator<RingEmotionalInfo> comparator = Comparator.comparingInt(info ->Integer.parseInt(info.getEmotionalState()));
        RingEmotionalInfo ringEmotionalInfo = ringEmotionalInfos.stream().max(comparator).orElse(null);
        int emotionScore = emotionScore(ringEmotionalInfo);
        conditionScoreVO.setEmotionScore(emotionScore);
        //压力
        RingStressChangeInfo ringStressChangeInfo = ringStressChangeInfoMapper.selectOneRingStressChangeInfo(Builder.of(RingStressChangeInfo::new).
                with(RingStressChangeInfo::setRecordTime, dailyValue).
                with(RingStressChangeInfo::setDeviceSn, physicalConditionDTO.getDeviceSn()).build());
        int pressureScore = pressureScore(ringStressChangeInfo);
        conditionScoreVO.setPressureScore(pressureScore);
        conditionScoreVO.setEmotionalStressScore(emotionScore+pressureScore);

        //饮食
        //早餐分数 */
        int breakfastScore = 0;
        //午餐分数 */
        int lunchScore = 0;
        //晚餐分数 */
        int dinnerScore = 0;
        //其他分数
        int otherScore = 0;
        UserFoodInfo userFoodInfo = new UserFoodInfo();
        userFoodInfo.setUserId(userId);
        userFoodInfo.setRecordDate(dailyValue);
        List<UserFoodInfo> userFoodInfos = userFoodInfoMapper.queryUserFoodInfoList(userFoodInfo);

        UserFoodInfo breakfast = userFoodInfos.stream().filter(info -> MealTypeEnums.BREAKFAST.getCode().equals(info.getMealType())).findFirst().orElse(null);
        if(breakfast != null){
            //卡路里(千卡)
            BigDecimal calories = breakfast.getCalories();
            //脂肪(g)
            BigDecimal fat = breakfast.getFat();
            // 蛋白质(g)
            BigDecimal protein = breakfast.getProtein();
            //碳水化合物(g)
            BigDecimal carbohydrate = breakfast.getCarbohydrate();
            if(calories.compareTo(BigDecimal.ZERO) > 0){
                int fatScore = queryResult(fat, calories);
                int proteinScore = queryResult(protein, calories);
                int carbohydrateScore = queryResult(carbohydrate, calories);
                boolean bl = foodInfoIsScore(fatScore,proteinScore,carbohydrateScore);
                breakfastScore = bl ? 1 : 0;
            }

        }

        UserFoodInfo lunch = userFoodInfos.stream().filter(info -> MealTypeEnums.LUNCH.getCode().equals(info.getMealType())).findFirst().orElse(null);
        if(lunch != null){
            //卡路里(千卡)
            BigDecimal calories = lunch.getCalories();
            //脂肪(g)
            BigDecimal fat = lunch.getFat();
            // 蛋白质(g)
            BigDecimal protein = lunch.getProtein();
            //碳水化合物(g)
            BigDecimal carbohydrate = lunch.getCarbohydrate();
            if(calories.compareTo(BigDecimal.ZERO) > 0){
                int fatScore = queryResult(fat, calories);
                int proteinScore = queryResult(protein, calories);
                int carbohydrateScore = queryResult(carbohydrate, calories);
                boolean bl = foodInfoIsScore(fatScore,proteinScore,carbohydrateScore);
                lunchScore = bl ? 2 : 1;
            }
        }

        UserFoodInfo dinner = userFoodInfos.stream().filter(info -> MealTypeEnums.DINNER.getCode().equals(info.getMealType())).findFirst().orElse(null);
        if(dinner != null) {
            //卡路里(千卡)
            BigDecimal calories = dinner.getCalories();
            //脂肪(g)
            BigDecimal fat = dinner.getFat();
            // 蛋白质(g)
            BigDecimal protein = dinner.getProtein();
            //碳水化合物(g)
            BigDecimal carbohydrate = dinner.getCarbohydrate();
            if (calories.compareTo(BigDecimal.ZERO) > 0) {
                int fatScore = queryResult(fat, calories);
                int proteinScore = queryResult(protein, calories);
                int carbohydrateScore = queryResult(carbohydrate, calories);
                boolean bl = foodInfoIsScore(fatScore,proteinScore,carbohydrateScore);
                dinnerScore = bl ? 2 : 1;
            }
        }
        conditionScoreVO.setBreakfastScore(breakfastScore);
        conditionScoreVO.setLunchScore(lunchScore);
        conditionScoreVO.setDinnerScore(dinnerScore);
        int foodTotalScore = breakfastScore+lunchScore+dinnerScore;
        if (foodTotalScore < 5){
            UserFoodInfo other = userFoodInfos.stream().filter(info ->MealTypeEnums.OTHER.getCode().equals(info.getMealType())).findFirst().orElse(null);
            if(other != null){
                otherScore = 1;
                foodTotalScore = foodTotalScore + otherScore;
            }
        }
        conditionScoreVO.setOtherScore(otherScore);
        conditionScoreVO.setFoodTotalScore(foodTotalScore);

        //体征
        int rateScore = 0;
        int hrvScore = 0;
        int oxygenScore = 0;
//        int restScore = 0;
        if(sleepId > 0){
            Date todayDate = longSleepDetail.getStartDate();//当天时间
            Date yesterday = null;//昨天日期
            Object result = isTodayOrGetYesterday(todayDate);
            if (result instanceof Date) {
                yesterday = (Date) result;
            }
            //睡眠信息（深度、浅度睡眠）
            List<RingSleepInfo> deepSleepInfos = queryRingSleepInfos(SleepClarityEnums.DEEP_SLEEP.getCode(),sleepId);
            List<RingSleepInfo> lightSleepInfos = queryRingSleepInfos(SleepClarityEnums.LIGHT_SLEEP.getCode(),sleepId);
            List<RingSleepInfo> sleepInfos = new ArrayList<>();
            sleepInfos.addAll(deepSleepInfos);
            sleepInfos.addAll(lightSleepInfos);
            List<Map<String, Date>> todayInfoList = queryIntervalList(sleepInfos,todayDate);

            Date today = DateUtils.dateTime(DateUtils.YYYY_MM_DD, DateUtils.dateTime(todayDate));
            //心率
            RingHeartRateInfo todayRateInfo = queryRingHeartRateInfo(longSleepDetail.getDeviceSn(),today);
            if(todayRateInfo != null){
                RingHeartRateInfo yesterdayRateInfo = null;
                if(yesterday != null){
                    yesterdayRateInfo = queryRingHeartRateInfo(longSleepDetail.getDeviceSn(),yesterday);
                }

                List<Integer> totalRateList = new ArrayList<>();
                for(Map<String, Date> map : todayInfoList){
                    queryValue(todayRateInfo.getHistoryDay(),todayRateInfo.getHeartRateList(), map.get("startTime"),  map.get("endTime"), totalRateList);
                    if(yesterdayRateInfo != null){
                        queryValue(yesterdayRateInfo.getHistoryDay(),yesterdayRateInfo.getHeartRateList(), map.get("startTime"),  map.get("endTime"), totalRateList);
                    }
                }
//            if(deepSleepInfos.size() == 0){
//                List<RingSleepInfo> lightSleepInfos = queryRingSleepInfos(SleepClarityEnums.LIGHT_SLEEP.getCode(),sleepId);
//                List<Map<String, Date>> todayInfoList = queryIntervalList(lightSleepInfos,today);
//                for(Map<String, Date> map : todayInfoList){
//                    queryValue(todayInfo.getStartTime(),todayInfo.getHeartRateList(), map.get("startTime"),  map.get("endTime()"), totalList);
//                    if(yesterdayInfo != null){
//                        queryValue(yesterdayInfo.getStartTime(),yesterdayInfo.getHeartRateList(), map.get("startTime"),  map.get("endTime()"), totalList);
//                    }
//                }
//            }else{
//                List<Map<String, Date>> todayInfoList = queryIntervalList(deepSleepInfos,today);
//                for(Map<String, Date> map : todayInfoList){
//                    queryValue(todayInfo.getStartTime(),todayInfo.getHeartRateList(), map.get("startTime"),  map.get("endTime()"), totalList);
//                    if(yesterdayInfo != null){
//                        queryValue(yesterdayInfo.getStartTime(),yesterdayInfo.getHeartRateList(), map.get("startTime"),  map.get("endTime()"), totalList);
//                    }
//                }
//            }
                List<Integer> rateList = totalRateList.stream().sorted().collect(Collectors.toList());
                int rateSize = rateList.size();
                // 计算前10%的元素数量
                if (rateSize  >0) {
                    // 计算前10%的元素数量，使用Math.ceil确保至少有1个元素（当列表长度小于10时）
                    int tenPercent = (int) Math.ceil(rateSize * 0.1);
                    // 提取前10%的元素并计算平均值
                    rateScore = queryRateScoreValue(Convert.toInt(rateList.stream().limit(tenPercent).mapToInt(Integer::intValue).average().orElse(0.0)));
//                    restScore = queryRateScoreValue(rateList.stream().mapToInt(Integer::intValue).min().orElse(0));
                }
            }


            //心率变异性
            RingHrvInfo todayHrvInfo = queryRingHrvInfo(longSleepDetail.getDeviceSn(),today);
            if(todayHrvInfo != null){
                RingHrvInfo yesterdayHrvInfo = null;
                if(yesterday != null){
                    yesterdayHrvInfo = queryRingHrvInfo(longSleepDetail.getDeviceSn(),yesterday);
                }
                List<Integer> totalHrvList = new ArrayList<>();
                for(Map<String, Date> map : todayInfoList){
                    queryValue(todayHrvInfo.getHistoryDay(),todayHrvInfo.getHrvList(), map.get("startTime"),  map.get("endTime"), totalHrvList);
                    if(yesterdayHrvInfo != null){
                        queryValue(yesterdayHrvInfo.getHistoryDay(),yesterdayHrvInfo.getHrvList(), map.get("startTime"),  map.get("endTime"), totalHrvList);
                    }
                }
                hrvScore = queryHrvScoreValue(Convert.toInt(totalHrvList.stream().mapToInt(Integer::intValue).average().orElse(0.0)));
            }

            //血氧饱和度
            RingBloodOxygen todayOxygenInfo = queryRingBloodOxygen(longSleepDetail.getDeviceSn(),today);
            if(todayOxygenInfo != null){
                RingBloodOxygen yesterdayOxygenInfo = null;
                if(yesterday != null){
                    yesterdayOxygenInfo = queryRingBloodOxygen(longSleepDetail.getDeviceSn(),yesterday);
                }
                List<Integer> totalOxygenList = new ArrayList<>();
                for(Map<String, Date> map : todayInfoList){
                    queryValue(todayOxygenInfo.getHistoryDay(),todayOxygenInfo.getBloodList(), map.get("startTime"),  map.get("endTime"), totalOxygenList);
                    if(yesterdayOxygenInfo != null){
                        queryValue(yesterdayOxygenInfo.getHistoryDay(),yesterdayOxygenInfo.getBloodList(), map.get("startTime"),  map.get("endTime"), totalOxygenList);
                    }
                }
                oxygenScore = queryOxygenValue(Convert.toInt(totalOxygenList.stream().mapToInt(Integer::intValue).average().orElse(0.0)));
            }


        }
        int physicalSignsScore = rateScore + hrvScore + oxygenScore;
        conditionScoreVO.setRateScore(rateScore);
//        conditionScoreVO.setRestScore(restScore);
        conditionScoreVO.setHrvScore(hrvScore);
        conditionScoreVO.setOxygenScore(oxygenScore);
        conditionScoreVO.setPhysicalSignsScore(physicalSignsScore);
        conditionScoreVO.setTotalScore(conditionScoreVO.getSleepTotalScore() +
                conditionScoreVO.getSportTotalScore() +
                conditionScoreVO.getEventTotalScore() +
                conditionScoreVO.getEmotionalStressScore() +
                conditionScoreVO.getFoodTotalScore() +
                conditionScoreVO.getPhysicalSignsScore());

        return conditionScoreVO;
    }

    /** 饮食分数
     * @param fatScore  脂肪(g)
     * @param proteinScore  蛋白质(g)
     * @param carbohydrateScore 碳水化合物(g)
     */
    public static Boolean foodInfoIsScore(int fatScore, int proteinScore, int carbohydrateScore){
        if (fatScore >= 15 && fatScore <= 35) {
            return true;
        }else if ( proteinScore >= 10 &&  proteinScore <= 25) {
            return true;
        } else if (carbohydrateScore >= 45 && carbohydrateScore <= 70) {
            return true;
        }else {
            return false;
        }
    }
    @Override
    public DashboardMetricsVO queryDashboardMetrics(PhysicalConditionDTO physicalConditionDTO) {
        long userId = SecurityUtils.getUserId();
        DashboardMetricsVO dashboardMetricsVO = new DashboardMetricsVO();
        int abnormal = 0;//记录异常项
        List<String> abnormalValues = new ArrayList<>();
        //健康计划
        RingHealthPlan healthPlan = ringHealthPlanService.selectOneRingHealthPlan(Builder.of(RingHealthPlan::new).
                with(RingHealthPlan::setUserId, userId).
                with(RingHealthPlan::setPlanStatus, PlanStatusEnums.IN_PROGRESS.getCode()).build());
        if(healthPlan != null){
            dashboardMetricsVO.setPlanStepCount(healthPlan.getStepCount());
            dashboardMetricsVO.setPlanSleepQuality(healthPlan.getSleepQuality());
            dashboardMetricsVO.setPlanRestingHeartRate(healthPlan.getRestingHeartRate());
            dashboardMetricsVO.setPlanHeartRateVariability(healthPlan.getHeartRateVariability());
            dashboardMetricsVO.setPlanBloodOxygenSaturation(healthPlan.getBloodOxygenSaturation());
        }


        Date pastDate = DateCalculationUtil.queryPastDate(physicalConditionDTO.getDailyValue(),1);
        //实际步数
        RingSportRecord sportRecord= ringSportRecordService.selectOneRingSportRecord(Builder.of(RingSportRecord::new).
                with(RingSportRecord::setCreateTime, physicalConditionDTO.getDailyValue()).
                with(RingSportRecord::setDeviceSn, physicalConditionDTO.getDeviceSn()).build());
        if(sportRecord != null){
            dashboardMetricsVO.setSteps(sportRecord.getSteps() == null ? 0 : sportRecord.getSteps());
            if(dashboardMetricsVO.getPlanStepCount() != null && dashboardMetricsVO.getPlanStepCount() > sportRecord.getSteps()){
                abnormalValues.add("实际步数存在异常项，步数小于设定步数，实际步数："+sportRecord.getSteps());
                abnormal = abnormal + 1;
            }
        }
        //实际睡眠质量评分
        RingSleepQualityScoreVO qualityScoreVO = ringSleepDetailService.queryQualityScore(Builder.of(RingSleepDetailInfoDTO::new).
                with(RingSleepDetailInfoDTO::setDeviceSn, physicalConditionDTO.getDeviceSn()).
                with(RingSleepDetailInfoDTO::setDailyValue, physicalConditionDTO.getDailyValue()).
                with(RingSleepDetailInfoDTO::setType, TimeUnitEnums.DAY.getCode()).build());
        if(qualityScoreVO != null){
            dashboardMetricsVO.setSleepScore(qualityScoreVO.getSleepScore());
            dashboardMetricsVO.setTiming(qualityScoreVO.getTiming());// TODO --
            if(dashboardMetricsVO.getTiming() != null && "差".equals(qualityScoreVO.getTiming())){
                abnormalValues.add("睡眠质量评分存在异常项，睡眠时机不好："+ qualityScoreVO.getTiming());
                abnormal = abnormal + 1;
            }
        }
        //实际静息心率
        SleepHomeRateVO heartRateVO0 = ringSleepDetailService.queryLongSleepHeartRate(Builder.of(RingSleepDetailInfoDTO::new).
                with(RingSleepDetailInfoDTO::setDeviceSn, physicalConditionDTO.getDeviceSn()).
                with(RingSleepDetailInfoDTO::setDailyValue, physicalConditionDTO.getDailyValue()).
                with(RingSleepDetailInfoDTO::setType, TimeUnitEnums.DAY.getCode()).build());
        int heartRate = heartRateVO0.getMinValue() == null ? 0 : heartRateVO0.getMinValue();
        dashboardMetricsVO.setHeartRate(heartRate);
        //实际前一天静息心率
        SleepHomeRateVO heartRateVO1 = ringSleepDetailService.queryLongSleepHeartRate(Builder.of(RingSleepDetailInfoDTO::new).
                with(RingSleepDetailInfoDTO::setDeviceSn, physicalConditionDTO.getDeviceSn()).
                with(RingSleepDetailInfoDTO::setDailyValue, pastDate).
                with(RingSleepDetailInfoDTO::setType, TimeUnitEnums.DAY.getCode()).build());

        int oldHeartRate = heartRateVO1.getMinValue() == null ? 0 : heartRateVO1.getMinValue();
        int value = heartRate-oldHeartRate;
        dashboardMetricsVO.setCompareHeartRate(value > 0 ? ("+"+value) : String.valueOf(value));

       if(healthPlan != null && healthPlan.getRestingHeartRate() != null){
           String[] rates = healthPlan.getRestingHeartRate().split("-");
           if(rates.length > 0){
               int value1 = Convert.toInt(rates[0].trim());
               int value2 = Convert.toInt(rates.length > 1 ?rates[1].trim() : 0);
               if(heartRate >= value2 || heartRate <= value1){
                   abnormal = abnormal + 1;
                   abnormalValues.add("静息心率存在异常项："+heartRate);
               }
           }
       }

        //实际心率变异性
        SleepHomeRateVO hrvVO0 = ringSleepDetailService.querySleepHrv(Builder.of(RingSleepDetailInfoDTO::new).
                with(RingSleepDetailInfoDTO::setDeviceSn, physicalConditionDTO.getDeviceSn()).
                with(RingSleepDetailInfoDTO::setDailyValue, physicalConditionDTO.getDailyValue()).
                with(RingSleepDetailInfoDTO::setType, TimeUnitEnums.DAY.getCode()).build());
        int heartHrv = hrvVO0.getAverage() == null ? 0 : hrvVO0.getAverage();
        dashboardMetricsVO.setHeartHrv(heartHrv);
        SleepHomeRateVO hrvVO1 = ringSleepDetailService.querySleepHrv(Builder.of(RingSleepDetailInfoDTO::new).
                with(RingSleepDetailInfoDTO::setDeviceSn, physicalConditionDTO.getDeviceSn()).
                with(RingSleepDetailInfoDTO::setDailyValue, pastDate).
                with(RingSleepDetailInfoDTO::setType, TimeUnitEnums.DAY.getCode()).build());
        int oldHeartHrv = hrvVO1.getAverage() == null ? 0 : hrvVO1.getAverage();
        int val = heartHrv-oldHeartHrv;
        dashboardMetricsVO.setCompareHeartHrv(val > 0 ? ("+"+val) : String.valueOf(val));

        if(healthPlan != null && healthPlan.getHeartRateVariability() != null){
            if(checkStringType(healthPlan.getHeartRateVariability())){
                String[] rates = healthPlan.getHeartRateVariability().split("-");
                if(rates.length > 0){
                    int value1 = Convert.toInt(rates[0].trim());
                    int value2 = Convert.toInt(rates.length > 1 ? rates[1].trim() : 0);
                    if(heartHrv >= value2 || heartHrv <= value1){
                        abnormal = abnormal + 1;
                        abnormalValues.add("心率变异性存在异常项："+heartHrv);
                    }
                }
            }
        }
        //实际血氧饱和
        SleepHomeRateVO oxygen = ringSleepDetailService.querySleepBloodOxygen(Builder.of(RingSleepDetailInfoDTO::new).
                with(RingSleepDetailInfoDTO::setDeviceSn, physicalConditionDTO.getDeviceSn()).
                with(RingSleepDetailInfoDTO::setDailyValue, physicalConditionDTO.getDailyValue()).
                with(RingSleepDetailInfoDTO::setType, TimeUnitEnums.DAY.getCode()).build());
        dashboardMetricsVO.setBloodOxygen(oxygen.getAverage() == null ? 0 : oxygen.getAverage());
        if(healthPlan != null && healthPlan.getBloodOxygenSaturation() != null){
            int bloodOxygen = dashboardMetricsVO.getBloodOxygen();
            if(checkStringType(healthPlan.getBloodOxygenSaturation())){
                String[] rates = healthPlan.getBloodOxygenSaturation().split("-");
                if(rates.length > 0){
                    int value1 = Convert.toInt(rates[0].trim());
                    int value2 = Convert.toInt(rates.length > 1 ? rates[1].trim() : 0);
                    if(bloodOxygen >= value2 || bloodOxygen <= value1){
                        abnormal = abnormal + 1;
                        abnormalValues.add("血氧饱和存在异常项："+bloodOxygen);
                    }
                }

            }
        }
        dashboardMetricsVO.setAbnormalValues(abnormalValues);
        dashboardMetricsVO.setAbnormalValue(queryAbnormalCount(abnormal));
        return dashboardMetricsVO;
    }
    public static String queryAbnormalCount(int abnormal){
        if(abnormal == 1){
            return "一项";
        }else if(abnormal == 2){
            return "两项";
        }else if(abnormal == 3){
            return "三项";
        }else if(abnormal == 4){
            return "四项";
        }else if(abnormal == 5){
            return "五项";
        }else {
            return "无";
        }
    }
    /**
     * 使用JDK8 Stream API判断字符串类型：纯汉字、纯数字、混合类型或空字符串
     * @param str 要检查的字符串
     * @return 字符串类型描述
     */
    public static Boolean checkStringType(String str) {
        if (str == null || str.isEmpty()) {
            return false;
        }
        // 重新获取字符流，检查是否全为汉字
        boolean allChinese = str.chars().allMatch(c -> c >= '\u4e00' && c <= '\u9fa5');
        if (allChinese) {
            return false;
        }else {
            return true;
        }
    }
    @Override
    public UserFoodInfo addFoodInfo(UserFoodInfoDTO userFoodInfoDTO) {
        long userId = SecurityUtils.getUserId();
        UserFoodInfo userFoodInfo = new UserFoodInfo();
        userFoodInfo.setUserId(userId);
        userFoodInfo.setRecordDate(new Date());
        userFoodInfo.setMealType(userFoodInfoDTO.getMealType());
        String result = "";
        String fileName = "";
        Gson gson = new Gson();
        if (userFoodInfoDTO.getFile().getSize() > 0){
            try {
                // 上传文件路径
                String filePath = RuoYiConfig.getUploadPath();
                // 上传并返回新文件名称
                fileName = FileUploadUtils.upload(filePath, userFoodInfoDTO.getFile());
                String apiHost = configService.selectConfigByKey("ring.api.host");
                log.info("apiHost : "+(apiHost + fileName));
                result = AiFactory.build(BizConstants.AI_PLATFORM.getValue()).chatImageCompletions(
                        "基于图片并以当前时间"+new Date() +"请给出就餐食物总名称，并汇总食物的脂肪、蛋白质、碳水化合物含量和卡路里千卡，不要给范围，直接取中间值就好。不要以makedown格式返回，只返回json格式，不要其他任何说明，json格式为{\"foodName\": \"xxx\", \"fat\": x, \"protein\": x, \"carbohydrate\": x, \"calories\": x}",
                        apiHost + fileName);
//                        "https://qcloud.dpfile.com/pc/AkY2XYlpiWzw3srgjX5L9mW6fuVcCzTuzH_lhpzCTOTLGChcZyc5rt217mHqjnZS.jpg");
            }
            catch (Exception e) {
                e.printStackTrace();
            }
        }else {
            String aiContent = userFoodInfoDTO.getDescription()+"请给出就餐食物总名称，并汇总食物的脂肪、蛋白质、碳水化合物含量和卡路里千卡，不要给范围，直接取中间值就好。不要以makedown格式返回，只返回json格式，不要其他任何说明，json格式为{\"foodName\": \"xxx\", \"fat\": x, \"protein\": x, \"carbohydrate\": x, \"calories\": x}";
            result = AiFactory.build(BizConstants.AI_PLATFORM.getValue()).chatCompletions(aiContent);

        }
        Map<String, Object> resultMap = gson.fromJson(result, Map.class);
        userFoodInfo.setFoodName(resultMap.get("foodName").toString());
        userFoodInfo.setCalories(BigDecimal.valueOf((double)resultMap.get("calories")));
        userFoodInfo.setFat(BigDecimal.valueOf((double)resultMap.get("fat")));
        userFoodInfo.setProtein(BigDecimal.valueOf((double)resultMap.get("protein")));
        userFoodInfo.setCarbohydrate(BigDecimal.valueOf((double)resultMap.get("carbohydrate")));
        userFoodInfo.setImageUrl(fileName);
        userFoodInfo.setDescription(userFoodInfoDTO.getDescription() == null ? "" : userFoodInfoDTO.getDescription());
        RingHealthPlan ringHealthPlan = ringHealthPlanService.selectOneRingHealthPlan(Builder.of(RingHealthPlan::new).
                with(RingHealthPlan::setUserId, userId).
                with(RingHealthPlan::setPlanStatus, PlanStatusEnums.IN_PROGRESS.getCode()).build());
        log.info("ringHealthPlan: {}", JSON.toJSONString(ringHealthPlan));
        if(ringHealthPlan != null && ringHealthPlan.getExerciseCalorie() != null && ringHealthPlan.getExerciseCalorie()> 0){
            String aiContent = "请将"+ringHealthPlan.getCalorie()+"千卡按照脂肪、蛋白质、碳水化合物含量以健康比例得出对应数值并转换成g。不要以makedown格式返回，只返回json格式，不要其他任何说明，json格式为{\"fat\": x, \"protein\": x, \"carbohydrate\": x}";
            String caloriesResult = AiFactory.build(BizConstants.AI_PLATFORM.getValue()).chatCompletions(aiContent);
            Map<String, Object> caloriesMap = gson.fromJson(caloriesResult, Map.class);
            userFoodInfo.setFatTotal(BigDecimal.valueOf((double)caloriesMap.get("fat")));
            userFoodInfo.setProteinTotal(BigDecimal.valueOf((double)caloriesMap.get("protein")));
            userFoodInfo.setCarbohydrateTotal(BigDecimal.valueOf((double)caloriesMap.get("carbohydrate")));
            userFoodInfo.setCaloriesTotal(ringHealthPlan.getExerciseCalorie());
        }
        int num = userFoodInfoService.insertUserFoodInfo(userFoodInfo);
        return num > 0 ? userFoodInfo : null;
    }

    @Override
    public RingEmotionalInfo addEmotionalInfoState(RingEmotionalInfoStateDTO emotionalInfoStateDTO) {
        long userId = SecurityUtils.getUserId();
        RingEmotionalInfo ringEmotionalInfo = cn.hutool.core.convert.Convert.convert(RingEmotionalInfo.class,emotionalInfoStateDTO);
        ringEmotionalInfo.setUserId(userId);
        ringEmotionalInfo.setDailyValue(DateUtils.dateTime(DateUtils.YYYY_MM_DD, DateUtils.getDate()));
        ringEmotionalInfo.setRecordTime(DateUtils.convertDateTimeToHHMM(new Date()));
        int result = ringEmotionalInfoService.insertRingEmotionalInfo(ringEmotionalInfo);
        return result > 0 ? ringEmotionalInfo : null;
    }

    @Override
    public EmotionalInfoOrStateVO queryEmotionalInfoOrState(PhysicalConditionDTO physicalConditionDTO) {
        long userId = SecurityUtils.getUserId();
        String deviceSn = physicalConditionDTO.getDeviceSn();
        Date dailyValue = physicalConditionDTO.getDailyValue();

        EmotionalInfoOrStateVO infoOrStateVO = new EmotionalInfoOrStateVO();
        List<EmotionalInfoOrStateVO.EmotionalStateInfo> emotionalStateList = new ArrayList<>();
        List<EmotionalInfoOrStateVO.StressChangeInfo> stressChangeInfoList = new ArrayList<>();
        RingStressChangeInfo ringStressChangeInfo = ringStressChangeInfoService.selectOneRingStressChangeInfo(Builder.of(RingStressChangeInfo::new).
                with(RingStressChangeInfo::setDeviceSn, deviceSn).
                with(RingStressChangeInfo::setUserId, userId).
                with(RingStressChangeInfo::setRecordTime, dailyValue).build());

        if(ringStressChangeInfo != null){
            RingHealthPlan ringHealthPlan = ringHealthPlanService.selectOneRingHealthPlan(Builder.of(RingHealthPlan::new).
                    with(RingHealthPlan::setUserId, userId).
                    with(RingHealthPlan::setPlanStatus, PlanStatusEnums.IN_PROGRESS.getCode()).build());
            infoOrStateVO.setEmotionManagement(ringHealthPlan == null ? null : ringHealthPlan.getEmotionManagement());
            List<RingEmotionalInfo> ringEmotionalInfos = ringEmotionalInfoService.selectRingEmotionalInfoList(Builder.of(RingEmotionalInfo::new).
                    with(RingEmotionalInfo::setUserId, userId).
                    with(RingEmotionalInfo::setDailyValue, dailyValue).build());
            if (ringEmotionalInfos.size() > 0){
                for(int i = 0; i< ringEmotionalInfos.size(); i++){
                    EmotionalInfoOrStateVO.EmotionalStateInfo em = new EmotionalInfoOrStateVO.EmotionalStateInfo();
                    RingEmotionalInfo ringEmotionalInfo = ringEmotionalInfos.get(i);
                    em.setEmotionalState(ringEmotionalInfo.getEmotionalState());
                    em.setRecordTime(ringEmotionalInfo.getRecordTime());
                    if(i == (ringEmotionalInfos.size() -1)){
                        infoOrStateVO.setEmotionalState(ringEmotionalInfo.getEmotionalState());
                        infoOrStateVO.setRecordTime(ringEmotionalInfo.getRecordTime());
                    }
                    emotionalStateList.add(em);
                }
                infoOrStateVO.setEmotionalStateList(emotionalStateList);
            }
            String changeList = ringStressChangeInfo.getStressChangeList();
            // 遍历所有心率数据点
            List<Integer> changeValueList = Arrays.stream(changeList.replace("null", "0").replace("255","0").split(","))
                    .map(String::trim) // 去除每个元素前后的空格
                    .map(Integer::parseInt) // 转换为整数
                    .collect(Collectors.toList());
            // 计算不等于0的元素的平均值
            double average = changeValueList.stream()
                    .filter(num -> num != 0)  // 过滤掉0值
                    .mapToInt(Integer::intValue)  // 转换为IntStream以使用average()方法
                    .average()  // 计算平均值
                    .orElse(0);  // 如果没有非零元素，返回0.0
            infoOrStateVO.setAverage(Convert.toInt(average));
            // 心率数据起始时间戳
            int intervalMs = 24 * 60 / changeValueList.size();
            // 计算每个数字对应的时间点
            for (int i = 0; i < changeValueList.size(); i++) {
                EmotionalInfoOrStateVO.StressChangeInfo info = new EmotionalInfoOrStateVO.StressChangeInfo();
                int num = changeValueList.get(i);
                // 计算当前心率数据点对应的时间戳
                int currentTimeMs = i * intervalMs;
                info.setTimeLabel(DateUtils.convertMinutesToHHMM(currentTimeMs));
                info.setValue(num);
                stressChangeInfoList.add(info);
            }
            infoOrStateVO.setRecordDate(DateUtils.datePath(dailyValue));
            infoOrStateVO.setWeekName(DateUtils.queryWeekday(dailyValue));
            infoOrStateVO.setStressChangeInfoList(stressChangeInfoList);
        }
        return infoOrStateVO;
    }

    @Override
    public DailyTags addDailyTag(DailyTags dailyTags) {
        String aiContent = dailyTags.getEventInfo()+", 请给以上描述打一个（-5到5）的分数，请以json格式直接返回评语和分数,分数为整数,例如：{\"pingyu\":\"xxx\",\"score\":x}，不要其他任何内容";
        String jsonStr = AiFactory.build(BizConstants.AI_PLATFORM.getValue()).chatCompletions(aiContent);
        Gson gson = new Gson();
        // 将JSON字符串转换为Map
        Map<String, Object> resultMap = gson.fromJson(jsonStr, Map.class);
        dailyTags.setDailyValue(DateUtils.dateTime(DateUtils.YYYY_MM_DD, DateUtils.getDate()));
        dailyTags.setAiCcomments(resultMap.get("pingyu").toString());
        DailyTags result = dailyTagsService.addTag(dailyTags);
        if(result != null){
            result.setRecordScores(resultMap.get("score").toString());
        }
        return result;
    }

    @Override
    public PhysicalActivitiesVO queryPhysicalActivities(PhysicalConditionDTO physicalConditionDTO) {
        long userId = SecurityUtils.getUserId();
        PhysicalActivitiesVO physicalActivitiesVO = new PhysicalActivitiesVO();
        RingHealthPlan ringHealthPlan = ringHealthPlanService.selectOneRingHealthPlan(Builder.of(RingHealthPlan::new).with(RingHealthPlan::setUserId, userId).with(RingHealthPlan::setPlanStatus, PlanStatusEnums.IN_PROGRESS.getCode()).build());
        RingSportRecord ringSportRecord = ringSportRecordService.selectOneRingSportRecord(Builder.of(RingSportRecord::new).with(RingSportRecord::setDeviceSn, physicalConditionDTO.getDeviceSn()).build());
        if(ringHealthPlan != null && ringSportRecord != null){
            double goalsSteps = Convert.toDouble(ringHealthPlan.getStepCount() == null ? 0 : ringHealthPlan.getStepCount());
            double goalsCalories = Convert.toDouble(ringHealthPlan.getExerciseCalorie() == null ? 0 : ringHealthPlan.getExerciseCalorie());
            double goalsSportTime = Convert.toDouble(ringHealthPlan.getExerciseDuration() == null ? 0 : ringHealthPlan.getExerciseDuration());
            double calories = Convert.toDouble(ringSportRecord.getCalories() == null ? 0 : ringSportRecord.getCalories());
            double steps = Convert.toDouble(ringSportRecord.getSteps() == null ? 0 : ringSportRecord.getSteps());
            double sportTime = Convert.toDouble(ringSportRecord.getSportTime());
            double caloriesScore = goalsCalories == 0 ? 0 : (calories/goalsCalories)*100;
            double stepsScore =  goalsSteps == 0 ? 0 : (steps/goalsSteps*100);
            double sportTimeScore =  goalsSportTime == 0 ? 0 : (sportTime/goalsSportTime*100);
            physicalActivitiesVO.setGoalsCalories(goalsCalories);
            physicalActivitiesVO.setGoalsSteps(goalsSteps);
            physicalActivitiesVO.setGoalsSportTime(goalsSportTime);
            physicalActivitiesVO.setCalories(calories);
            physicalActivitiesVO.setSteps(steps);
            physicalActivitiesVO.setSportTime(sportTime);
            physicalActivitiesVO.setCaloriesScore(Convert.toInt(caloriesScore));
            physicalActivitiesVO.setStepsScore(Convert.toInt(stepsScore));
            physicalActivitiesVO.setSportTimeScore(Convert.toInt(sportTimeScore));
        }
        return physicalActivitiesVO;
    }

    @Override
    public ExerciseRecordsVO queryExerciseRecords(PhysicalConditionDTO physicalConditionDTO) {
        long userId = SecurityUtils.getUserId();
        ExerciseRecordsVO exerciseRecordsVO = new ExerciseRecordsVO();
        List<RingExerciseDetail> list = ringExerciseDetailService.selectRingExerciseDetailList(Builder.of(RingExerciseDetail::new).with(RingExerciseDetail::setUserId, userId).with(RingExerciseDetail::setRecordDate, physicalConditionDTO.getDailyValue()).build());
        int total = list.size();
        if(total > 0){
            long exerciseTime = list.stream().mapToLong(r -> r.getValidTime()).sum();// 运动时长
            long exerciseCalorie = list.stream().mapToLong(r -> r.getCalories()).sum();// 运动卡路里
            exerciseRecordsVO.setExerciseTime(exerciseTime);
            exerciseRecordsVO.setExerciseCalorie(exerciseCalorie);
            exerciseRecordsVO.setTotal(total);
        }
        return exerciseRecordsVO;
    }

    @Override
    public RingHeartRateInfoVO queryHeartRateInfo(RingHeartRateInfoDTO heartRateInfoDTO) {
        RingHeartRateInfoVO ringHeartRateInfoVO = new RingHeartRateInfoVO();
        RingSleepDetail ringSleepDetail = ringSleepDetailService.selectOneRingSleepDetail(Builder.of(RingSleepDetail::new).
                with(RingSleepDetail::setDeviceSn,heartRateInfoDTO.getDeviceSn()).
                with(RingSleepDetail::setSleepType,SleepTypeEnums.LONG_SLEEP.getCode()).
                with(RingSleepDetail::setDailyValue,heartRateInfoDTO.getHistoryDay()).build());
        if(ringSleepDetail != null){
            ringHeartRateInfoVO.setStartTime(DateUtils.convertDateTimeToHHMM(ringSleepDetail.getStartDate()));
            ringHeartRateInfoVO.setEndTime(DateUtils.convertDateTimeToHHMM(ringSleepDetail.getEndDate()));
        }
        List<RingHeartRateInfo> list = ringHeartRateInfoMapper.queryRingHeartRateInfoList(heartRateInfoDTO);
        if(list.size() > 0){
            RingHeartRateInfo heartRateInfo = list.get(0);
            String[] rateInfos = heartRateInfo.getHeartRateList().split(",");//转成String数组
            int[] rates = Stream.of(rateInfos).mapToInt(Integer::parseInt).toArray();//转成int数组
            ringHeartRateInfoVO.setAverageValue((int)Arrays.stream(rates).filter(num -> num != 0).average().orElse(0));
            List<RingHeartRateInfoVO.HeartRate> heartRateList = new ArrayList<>();
            for(int i = 0; i< rates.length; i++){
                int rate = rates[i];
                RingHeartRateInfoVO.HeartRate heartRate = new RingHeartRateInfoVO.HeartRate();
                // 计算当前时间（分钟）：初始0分钟，每次增加5分钟
                int minutes = i * heartRateInfo.getTimeInterval();
                // 格式化时间为HH:MM格式（补前导零）
                heartRate.setTimeLabel(DateUtils.convertMinutesToHHMM(minutes));
                heartRate.setValue(String.valueOf(rate));
                heartRateList.add(heartRate);
            }
            ringHeartRateInfoVO.setHeartRateList(heartRateList);
        }
        return ringHeartRateInfoVO;
    }

    @Override
    public RingHrvInfoVO queryRingHrvInfo(RingHrvInfoDTO ringHrvInfoDTO) {
        RingHrvInfoVO ringHrvInfoVO = new RingHrvInfoVO();
        List<RingHrvInfo> list = ringHrvInfoMapper.queryRingHrvInfoList(ringHrvInfoDTO);
        if(list.size() > 0){
            RingHrvInfo hrvInfo = list.get(0);
            String[] hrvInfos = Arrays.stream(hrvInfo.getHrvList().split(","))
                    .filter(s -> s != null && !s.equalsIgnoreCase("null") && !s.isEmpty())
                    .toArray(String[]::new);
            int[] hrvs = Stream.of(hrvInfos).mapToInt(Integer::parseInt).toArray();//转成int数组
            ringHrvInfoVO.setAverageValue((int) Arrays.stream(hrvs).filter(num -> num != 0).average().orElse(0));
            List<RingHrvInfoVO.RingHrv> ringHrvList = new ArrayList<>();
            int timeInterval = 24*60/hrvs.length;
            for(int i = 0; i< hrvs.length; i++){
                int hrv = hrvs[i];
                RingHrvInfoVO.RingHrv ringHrv = new RingHrvInfoVO.RingHrv();
                // 计算当前时间（分钟）：初始0分钟，每次增加5分钟
                int minutes = i * timeInterval;
                ringHrv.setTimeLabel(DateUtils.convertMinutesToHHMM(minutes));
                ringHrv.setValue(String.valueOf(hrv));
                ringHrvList.add(ringHrv);
            }
            ringHrvInfoVO.setHrvList(ringHrvList);
        }
        return ringHrvInfoVO;
    }

    @Override
    public RingSleepHeartRateVO querySleepBloodOxygen(RingSleepDetailInfoDTO sleepDetailInfoDTO) {
        RingSleepHeartRateVO sleepHeartRateVO = new RingSleepHeartRateVO();
        RingBloodOxygen ringBloodOxygen = ringBloodOxygenMapper.selectOneRingBloodOxygen(Builder.of(RingBloodOxygen::new).
                with(RingBloodOxygen::setDeviceSn, sleepDetailInfoDTO.getDeviceSn()).
                with(RingBloodOxygen::setDailyValue, sleepDetailInfoDTO.getDailyValue()).build());
        if(ringBloodOxygen != null){

            String strValue = ringBloodOxygen.getBloodList().replace("null", "0").replace("255","0");
            String[] bloodOxygen = strValue.split(",");//转成String数组
            int[] bloodOxygens = Stream.of(bloodOxygen).mapToInt(Integer::parseInt).toArray();//转成int数组
            sleepHeartRateVO.setAverage((int)Arrays.stream(bloodOxygens).filter(num -> num != 0).average().orElse(0));
            List<RingSleepHeartRateVO.RingSleepHeartRate> heartRateList = new ArrayList<>();
            int timeInterval = 24*60/bloodOxygens.length;
            for(int i = 0; i< bloodOxygens.length; i++){
                int bo = bloodOxygens[i];
                RingSleepHeartRateVO.RingSleepHeartRate heartRate = new RingSleepHeartRateVO.RingSleepHeartRate();
                // 计算当前时间（分钟）：初始0分钟，每次增加5分钟
                int minutes = i * timeInterval;
                // 格式化时间为HH:MM格式（补前导零）
                heartRate.setKey(DateUtils.convertMinutesToHHMM(minutes));
                heartRate.setValue(bo);
                heartRateList.add(heartRate);
            }
            sleepHeartRateVO.setHeartRateList(heartRateList);
        }
        return sleepHeartRateVO;
    }

    @Override
    public MenstrualCycleVO queryMenstrualCycle(PhysicalConditionDTO physicalConditionDTO) {
        long userId = SecurityUtils.getUserId();
        UserPhysiologyVO userPhysiologyVO;
        PhysiologyInfoQueryDTO queryDTO = new PhysiologyInfoQueryDTO();
        queryDTO.setUserId(userId);
        queryDTO.setSelectDate(physicalConditionDTO.getDailyValue());
        Date selectDate = queryDTO.getSelectDate();// 选择的时间
        //生理周期设置
        UserPhysiologySet physiologySet = userPhysiologySetMapper.selectOneUserPhysiologySet(Builder.of(UserPhysiologySet::new).with(UserPhysiologySet::setUserId, userId).build());
        if(physiologySet != null){
            //周期信息
            UserPhysiology userPhysiology = userPhysiologyMapper.queryOnePhysiologyInfo(queryDTO);
            if (!DateUtils.isAfterAndDifferentMonth(queryDTO.getSelectDate(),new Date()) && userPhysiology == null){
                return new MenstrualCycleVO();
            }
            if(userPhysiology != null){
                userPhysiologyVO = Convert.convert(UserPhysiologyVO.class,userPhysiology);
            }else {
                long menstrualPeriodDays = physiologySet.getMenstrualPeriodDays(); // 生理期天数;
                long periodDays = physiologySet.getPeriodDays(); // 周期间隔天数
                Date startDate = queryDTO.getUpdStartDate() != null ? queryDTO.getUpdStartDate() : physiologySet.getStartDate(); // 上次生理期开始日期
                userPhysiologyVO = processMonth(startDate, selectDate, Convert.toInt(menstrualPeriodDays), Convert.toInt(periodDays));
            }

            // 生理期（记录日用逗号隔开）
            String menstrualPeriod = userPhysiologyVO.getMenstrualPeriod();
            // 排卵期（记录日用逗号隔开）
            String ovulationPeriod = userPhysiologyVO.getOvulationPeriod();
            MenstrualCycleVO menstrualCycleVO = calculateCycle(selectDate,menstrualPeriod,ovulationPeriod);
            return menstrualCycleVO;
        }else {
            MenstrualCycleVO menstrualCycleVO = calculateCycle(selectDate,null,null);
            return menstrualCycleVO;
        }
    }
    public static MenstrualCycleVO calculateCycle(Date currentDate, String menstrualPeriod, String ovulationPeriod) {
        MenstrualCycleVO vo = new MenstrualCycleVO();

        // 使用Calendar处理日期
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(currentDate);
        // 设置月份
        vo.setMonth((calendar.get(Calendar.MONTH) + 1) +"月"); // 月份从0开始，需要+1
        // 解析生理期和排卵期的日期集合
        Set<String> menstrualDays = parseDays(menstrualPeriod);
        Set<String> ovulationDays = parseDays(ovulationPeriod);
        // 存储结果的列表
        List<MenstrualCycleVO.ResultVO> resultVOS = new ArrayList<>();
        // 计算当前日期的前三天和后三天（共7天：-3, -2, -1, 0, +1, +2, +3）
        for (int i = -3; i <= 3; i++) {
            // 复制当前日期的Calendar实例，避免修改原始对象
            Calendar tempCalendar = (Calendar) calendar.clone();
            tempCalendar.add(Calendar.DAY_OF_MONTH, i);
            int day = tempCalendar.get(Calendar.DAY_OF_MONTH);
            // 获取星期几（转换为中文）
            String weekName = getChineseWeekDay(tempCalendar.get(Calendar.DAY_OF_WEEK));
            // 格式化日期（dd）
            String dayStr = String.format("%02d", day);
            // 创建ResultVO对象
            MenstrualCycleVO.ResultVO resultVO = new MenstrualCycleVO.ResultVO();
            resultVO.setValue(dayStr);
            resultVO.setWeekName(weekName);
            // 判断属于哪个周期并添加到相应列表
            if (menstrualDays.contains(day)) {
                resultVO.setType("1");
            }else if (ovulationDays.contains(day)) {
                resultVO.setType("2");
            }else {
                resultVO.setType("0");
            }
            resultVOS.add(resultVO);
        }

        // 设置结果列表
        vo.setResultVOS(resultVOS);
        return vo;
    }

    // 解析以逗号分隔的日期字符串为Set集合
    private static Set<String> parseDays(String period) {
        Set<String> days = new HashSet<>();
        if (period == null || period.isEmpty()) {
            return days;
        }
        Arrays.stream(period.split(",")).forEach(dayStr -> days.add(dayStr));
        return days;
    }

    // 将Calendar的星期值转换为中文星期（Calendar的星期从周日开始，值为1-7）
    private static String getChineseWeekDay(int dayOfWeek) {
        switch (dayOfWeek) {
            case Calendar.MONDAY: return "一";
            case Calendar.TUESDAY: return "二";
            case Calendar.WEDNESDAY: return "三";
            case Calendar.THURSDAY: return "四";
            case Calendar.FRIDAY: return "五";
            case Calendar.SATURDAY: return "六";
            case Calendar.SUNDAY: return "日";
            default: return "";
        }
    }
    /**
     * 处理后续月份的生理周期数据
     * @param startDate 生理期开始日期
     * @param selectDate 目标月份日期
     * @param menstrualPeriodDays 生理期天数
     * @param periodDays 周期间隔天数
     * @return 后续月份生理周期数据VO
     */
    private UserPhysiologyVO processMonth(Date startDate, Date selectDate, Integer menstrualPeriodDays, Integer periodDays) {
        UserPhysiologyVO vo = new UserPhysiologyVO();
        // 计算目标月份内的生理期日期
        int monthOffset = DateUtils.queryMonthsDifference(startDate,selectDate);
        Date periodStartDate = DateUtils.queryMonthOfYear(startDate,monthOffset*periodDays);
//        log.info("初始: " + DateUtils.dateTime(periodStartDate));
        Date periodEndDate = predictNextPeriodEnd(periodStartDate, menstrualPeriodDays);
        Date ovulationDayDate = predictOvulationDay(periodStartDate);
        Date predictFertileStart = predictFertileStart(ovulationDayDate);
        Date predictFertileEnd = predictFertileEnd(ovulationDayDate);
        Date nextPeriodStartDate = predictNextPeriodStart(periodStartDate, periodDays);
        Date nextPeriodEndDate = predictNextPeriodEnd(nextPeriodStartDate, menstrualPeriodDays);

        // 生理期（记录日用逗号隔开）
        List<String> mpDays = DateUtils.getDayStringsBetweenDates(periodStartDate,periodEndDate);
        String menstrualPeriod = mpDays.stream().collect(Collectors.joining(","));

        // 排卵日 */
        String ovulationDay = Convert.toStr(DateUtils.queryDayOfMonth(ovulationDayDate));

        // 排卵期（记录日用逗号隔开）
        List<String> opDays = DateUtils.getDayStringsBetweenDates(predictFertileStart,predictFertileEnd);
        String ovulationPeriod = opDays.stream().collect(Collectors.joining(","));

        // 预测生理期（记录日用逗号隔开）
        List<String> days = DateUtils.getDayStringsBetweenDates(nextPeriodStartDate,nextPeriodEndDate);
        String predictMenstrualPeriod = days.stream().collect(Collectors.joining(","));

        // 更新本月生理期开始日期
        Date updStartDate = periodStartDate;

        // 更新本月生理期结束日期
        Date updEndDate = periodEndDate;

        vo.setMenstrualPeriod(menstrualPeriod);
        vo.setOvulationDay(ovulationDay);
        vo.setOvulationPeriod(ovulationPeriod);
        vo.setPredictMenstrualPeriod(predictMenstrualPeriod);
        vo.setUpdStartDate(updStartDate);
        vo.setUpdEndDate(updEndDate);
        return vo;
    }
    /**
     * 月经期开始日
     * @param startDate 月经期开始日
     * @param cycleDays 月经周期天数
     */
    public static Date predictNextPeriodStart(Date startDate, int cycleDays) {
        return DateUtils.addDays(startDate, cycleDays);
    }

    /**
     * 月经期结束日
     * @param startDate 月经期开始日
     * @param periodDays 经期持续天数
     */
    public static Date predictNextPeriodEnd(Date startDate, int periodDays) {
        // 例如：1号开始，持续5天，结束日是 1 + 5 - 1 = 5号
        return DateUtils.addDays(startDate, periodDays - 1);
    }
    /**
     * 预测排卵日
     * 医学上通常认为排卵日发生在下次月经来潮前的14天左右。
     * @param startDate 月经期开始日
     */
    public static Date predictOvulationDay(Date startDate) {
        return DateUtils.addDays(startDate, 14);
    }

    /**
     * 预测易孕期/排卵期
     * 通常是指排卵日的前5天和后2天，共7天。
     * @param ovulationDay 预测的排卵日
     * @return 包含易孕期开始和结束日期的 FertilePeriod 对象
     */
    public static Date predictFertileStart(Date ovulationDay) {
        return DateUtils.addDays(ovulationDay, -5);
    }
    /**
     * 预测易孕期/排卵期
     * 通常是指排卵日的前5天和后2天，共7天。
     * @param ovulationDay 预测的排卵日
     * @return 包含易孕期开始和结束日期的 FertilePeriod 对象
     */
    public static Date predictFertileEnd(Date ovulationDay) {
        return DateUtils.addDays(ovulationDay, 2);
    }
    /**
     * 心率得分
     */
    public static Integer queryRateScoreValue(int value) {
        if (value > 60 && value <= 80) {
            return 5;
        } else if ((value > 55 && value <= 59) || (value > 81 && value <= 85)) {
            return 3;
        } else {
            return 1;
        }
    }

    /**
     * 心率变异性得分
     */
    public static Integer queryHrvScoreValue(int value) {
        if (value > 50) {
            return 10;
        } else if (value > 30 && value <= 50) {
            return 8;
        } else if (value > 10 && value <= 29) {
            return 6;
        } else {
            return 5;
        }
    }

    /**
     * 血氧饱和度得分
     */
    public static Integer queryOxygenValue(int value) {
        if (value > 90 && value <= 100) {
            return 5;
        } else if (value > 85 && value <= 89) {
            return 3;
        } else {
            return 1;
        }
    }
    /**
     * 获取时间区间集合
     */
    public List<Map<String, Date>> queryIntervalList(List<RingSleepInfo> ringSleepInfoList, Date startDate){
        List<Map<String, Date>> mapList = new ArrayList<>();
        // 将Date转换为LocalDateTime（需指定时区，这里用系统默认时区）
        LocalDateTime localDateTime = startDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
        // 获取分钟（0-59）
        int minute = localDateTime.getMinute();
        ringSleepInfoList.stream().sorted(Comparator.comparing(RingSleepInfo::getId)).collect(Collectors.toList()).forEach(r ->{
            Map<String, Date> map = new HashMap<>();
            map.put("startTime", DateUtils.queryDate(startDate,r.getStartTime()-minute));
            map.put("endTime", DateUtils.queryDate(startDate,r.getEndTime()-minute));
            mapList.add(map);
        });
        return mapList;
    }
    /**
     * 获取心率信息
     */
    public RingHeartRateInfo queryRingHeartRateInfo(String deviceSn,Date date){
        return ringHeartRateInfoMapper.selectOneRingHeartRateInfo(Builder.of(RingHeartRateInfo::new).
                with(RingHeartRateInfo::setDeviceSn, deviceSn).
                with(RingHeartRateInfo::setDailyValue, date).build());
    }

    /**
     * 获取心率变异性信息
     */
    public RingHrvInfo queryRingHrvInfo(String deviceSn,Date date){
        return ringHrvInfoMapper.selectOneRingHrvInfo(Builder.of(RingHrvInfo::new).
                with(RingHrvInfo::setDeviceSn, deviceSn).
                with(RingHrvInfo::setDailyValue, date).build());
    }

    /**
     * 获取血氧饱和度信息
     */
    public RingBloodOxygen queryRingBloodOxygen(String deviceSn,Date date){
        return ringBloodOxygenMapper.selectOneRingBloodOxygen(Builder.of(RingBloodOxygen::new).
                with(RingBloodOxygen::setDeviceSn, deviceSn).
                with(RingBloodOxygen::setDailyValue, date).build());
    }

    /**
     * 获取睡眠信息
     */
    public List<RingSleepInfo> queryRingSleepInfos(Integer sleepClarity, Long sleepId){
        return ringSleepInfoMapper.selectRingSleepInfoList(Builder.of(RingSleepInfo::new).
                with(RingSleepInfo::setRingSleepId, sleepId).
                with(RingSleepInfo::setSleepType, sleepClarity).build());
    }

    /**
     * 判断日期是否为今天，如果不是则返回该日期的上一天（仅包含年月日信息）
     * @param startDate 要判断的日期
     * @return 如果是今天返回true，否则返回上一天的Date对象（时间部分为00:00:00）
     */
    public static Object isTodayOrGetYesterday(Date startDate) {
        // 将Date转换为LocalDate（Java 8及以上）
        LocalDate targetDate = startDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        // 获取今天的日期
        LocalDate today = LocalDate.now();

        if (targetDate.equals(today)) {
            // 如果是今天，返回true
            return true;
        } else {
            return DateUtils.queryYesterday(startDate);
        }
    }

    /**
     * @param strValue 逗号隔开的字符串
     * @return 时间戳与心率的映射列表，按时间排序
     */
    public void queryValue(Date latest,String strValue, Date startDate, Date endDate, List<Integer> totalList) {
        long startMs = latest.getTime();
        // 遍历所有心率数据点
        List<Integer> list = Arrays.stream(strValue.replace("null", "0").replace("255","0").split(","))
                .map(String::trim) // 去除每个元素前后的空格
                .map(Integer::parseInt) // 转换为整数
                .collect(Collectors.toList());
        // 转换时间单位：秒 -> 毫秒
        long intervalMs = 24 * 60 / list.size() * 60L * 1000L;
        for (int i = 0; i < list.size(); i++) {
            // 计算当前心率数据点对应的时间戳
            long currentTimeMs = startMs + (long)i * intervalMs;
            // 检查该时间点是否在睡眠期间内
            if (currentTimeMs >= startDate.getTime() && currentTimeMs <= endDate.getTime()) {
                int value = list.get(i);
                // 仅添加有效值(排除0值)
                if (value > 0) {
                    totalList.add(value);
                }
            }
        }
    }
    /**
     * 计算睡眠时长得分
     */
    public static Integer calculateSleepDurationScore(RingSleepDetail sleepDetail) {
        if(sleepDetail != null){
            int totalTime = sleepDetail.getTotalTime();
            if (totalTime > 420) {
                return 15;
            } else if (totalTime >= 300) {
                return 13;
            } else if (totalTime >= 180) {
                return 11;
            } else {
                return 9;
            }
        }else {
            return 0;
        }

    }
    /**
     * 计算深睡眠比例得分
     */
    public static Integer calculateDeepSleepRatioScore(RingSleepDetail sleepDetail) {
        if(sleepDetail != null){
            double totalTime=(double) sleepDetail.getTotalTime();
            double deepTime=(double) sleepDetail.getDeepTime();
            // 计算深睡眠比例(百分比)
            double deepRatio = deepTime / totalTime * 100;
            if (deepRatio >= 20) {
                return 10;
            } else if (deepRatio >= 15) {
                return 8;
            } else if (deepRatio >= 10) {
                return 6;
            } else {
                return 4;
            }
        }else {
            return 0;
        }
    }
    /**
     * 睡眠效率
     * @param sleepDetail
     * @return
     */
    public static Integer sleepEfficiency(RingSleepDetail sleepDetail) {
        int sleepTime = sleepDetail.getTotalTime();//睡眠时间
        int bedriddenTime = sleepDetail.getAwakeTime() + sleepTime;//卧床时间
        // 避免除以零的情况
        if (bedriddenTime <= 0) {
            return 0;
        }
        double efficiency = Convert.toDouble(sleepTime) / Convert.toDouble(bedriddenTime) * 100;
        int resultl =  Convert.toInt(Math.round(efficiency));
        if (resultl >= 85) {
            return 10;
        } else if (resultl > 80) {
            return 9;
        } else if (resultl > 70) {
            return 7;
        } else if (resultl > 65) {
            return 5;
        } else {
            return 0;
        }
    }
    /**
     * 计算小睡得分
     * 规则：
     * - 小睡开始时间在12:00-16:00范围内：5分
     * - 不在范围内但有短睡眠：3分
     * - 没有短睡眠：0分
     */
    public static Integer calculateNapScore(RingSleepDetail shortSleepDetail) {
        if (shortSleepDetail != null) {
            // 使用Calendar获取小时数
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(shortSleepDetail.getStartDate());
            int hour = calendar.get(Calendar.HOUR_OF_DAY); // 24小时制
            // 判断是否在12:00-16:00之间
            if (hour >= 12 && hour < 16) {
                return 5;
            } else {
                return 3;
            }
        }else {
            return 0;
        }

    }
    /**
     * BMI指数
     */
    public static Integer BMICalculator(double height,double weight) {
        // 正确计算身高（米）：先转换为double再除以100
        double heightInMeters = height / 100.0;
        System.out.println("身高（米）: " + heightInMeters);
        // 计算BMI：体重(kg) ÷ (身高(m)的平方)
        double bmi = weight / (heightInMeters * heightInMeters);
        System.out.println("原始BMI值: " + bmi);
        // 向上取整保留两位小数
        double bmiRoundedUp = Math.ceil(bmi * 100) / 100;
        System.out.println("向上取整保留两位小数的BMI值: " + bmiRoundedUp);
        // 根据BMI值判断体型
        String category;
        int score;

        if (bmiRoundedUp >= 18.5 && bmiRoundedUp <= 23.9) {
            category = "正常";
            score = 4;
        } else if ((bmiRoundedUp >= 24 && bmiRoundedUp <= 27.9) ||
                (bmiRoundedUp >= 17 && bmiRoundedUp < 18.5)) {
            category = (bmiRoundedUp >= 24) ? "超重" : "偏轻";
            score = 2;
        } else if (bmiRoundedUp >= 28 || bmiRoundedUp < 17) {
            category = (bmiRoundedUp >= 28) ? "肥胖" : "过轻";
            score = 1;
        } else {
            category = "未知";
            score = 0;
        }
        return score;
    }
    /**
     * 计算步数对应的评分
     * @param actualSteps 实际步数
     * @param targetSteps 设定的目标步数
     * @return 对应的分数
     */
    public static int calculateStepScore(int actualSteps, int targetSteps) {
        if (actualSteps >= targetSteps) {
            return 6; // 达到或超过设定步数，得6分
        } else if (actualSteps >= targetSteps * 0.8 && actualSteps < targetSteps) {
            return 4; // 达到设定步数的80%-99%，得4分
        } else if (actualSteps >= targetSteps * 0.5 && actualSteps < targetSteps * 0.8) {
            return 2; // 达到设定步数的50%-79%，得2分
        } else {
            return 1; // 低于设定步数的50%，得1分
        }
    }
    /**
     * 计算运动距离对应的评分
     * @param distance 实际运动距离（米）
     * @return 对应的分数
     */
    public static int calculateDistanceScore(double distance) {
        if (distance >= 3000) {
            return 6; // ≥3000米，得6分
        } else if (distance >= 2000 && distance < 3000) {
            return 4; // 2000-2999米，得4分
        } else if (distance >= 1000 && distance < 2000) {
            return 2; // 1000-1999米，得2分
        } else {
            return 1; // <1000米，得1分
        }
    }
    /**
     * 计算卡路里消耗对应的评分
     * @param actualCalories 实际消耗的卡路里
     * @param targetCalories 当日目标卡路里消耗
     * @return 对应的分数
     */
    public static int calculateCalorieScore(double actualCalories, double targetCalories) {
        if (actualCalories >= targetCalories) {
            return 4; // 达到或超过目标消耗，得4分
        } else if (actualCalories >= targetCalories * 0.8 && actualCalories < targetCalories) {
            return 2; // 达到目标消耗的80%-99%，得2分
        } else {
            return 1; // 低于目标消耗的80%，得1分
        }
    }

    /** 情绪 */
    public static Integer emotionScore(RingEmotionalInfo ringEmotionalInfo) {
        if(ringEmotionalInfo != null){
            int emotionalState = Convert.toInt(ringEmotionalInfo.getEmotionalState());
            if (emotionalState == 3 || emotionalState == 4 || emotionalState == 5) {
                return 5;
            } else {
                return 3;
            }
        }else {
            return 0;
        }
    }

    /** 压力 */
    public static Integer pressureScore(RingStressChangeInfo ringStressChangeInfo ) {
        if(ringStressChangeInfo != null){
            // 遍历所有心率数据点
            List<Integer> changeValueList = Arrays.stream(ringStressChangeInfo.getStressChangeList().replace("null", "0").replace("255", "0").split(","))
                    .map(String::trim) // 去除每个元素前后的空格
                    .map(Integer::parseInt) // 转换为整数
                    .collect(Collectors.toList());
            // 计算不等于0的元素的平均值
            double average = changeValueList.stream()
                    .filter(num -> num != 0)  // 过滤掉0值
                    .mapToInt(Integer::intValue)  // 转换为IntStream以使用average()方法
                    .average()  // 计算平均值
                    .orElse(0);  // 如果没有非零元素，返回0.0
            if (average >= 80) {
                return 1;
            } else if (average >= 50 && average <= 79) {
                return 2;
            } else if (average >= 30 && average <= 49) {
                return 4;
            } else {
                return 5;
            }
        }else {
            return 0;
        }
    }

    /** BigDecimal相除计算 */
    private static Integer queryResult(BigDecimal paramValue,BigDecimal calories){
        BigDecimal result = paramValue.divide(calories, 2, RoundingMode.HALF_UP);
        // 乘以100
        BigDecimal finalResult = result.multiply(new BigDecimal("100"));
        return finalResult.intValue();
    }

}
